package ua.org.enginer.controls
{
	
import flash.filters.DropShadowFilter;

import mx.core.UIComponent;

//--------------------------------------
//  Styles
//--------------------------------------

/**
 *  @default 1
 */
[Style(name="borderThickness", type="Number", inherit="no")]

/**
 *  Thickness of line of divider inside the circle
 * 
 *  @default 1
 */
[Style(name="lineThickness", type="Number", inherit="no")]

/**
 *  @default 1
 */
[Style(name="borderAlpha", type="Number", inherit="no")]

/**
 *  @default 1
 */
[Style(name="lineAlpha", type="Number", inherit="no")]

/**
 *  @default 0
 */
[Style(name="borderColor", type="uint", format="Color", inherit="no")]

/**
 *  @default 0
 */
[Style(name="lineColor", type="uint", format="Color", inherit="no")]

/**
 *  @default .8
 */
[Style(name="fillAlpha", type="Number", inherit="no")]

/**
 *  @default yes
 */
[Style(name="dropShadow", enumeration="yes,no", inherit="no")]

public class PieIcon extends UIComponent
{
	public static const MAX_RADIUS:int = 25
	public static const MIN_RADIUS:int = 5
	
	private var _lineThickness:Number = 1
	private var _lineAlpha:Number = 1
	private var _lineColor:uint = 0
	
	private var _borderThickness:Number = 1
	private var _borderAlpha:Number = 1
	private var _borderColor:uint = 0
	
	private var _fillAlpha:Number = .8
	
	public var values:Array = []
	
	private var _totalValue:Number = 0
	
	public function get totalValue():Number {
		return _totalValue;
	}

	
	//private var shadow:DropShadowFilter
	
	protected var radius:Number
	public static var maxValue:Number
	
	public function PieIcon()
	{
		super();
		//alpha = .8
	}
	
	public function addValue(label:String, value:Number, color:uint):void {
		values.push({label:label, value:value, color:color})
		_totalValue += value
		toolTip += "\n"+label+" - "+value
		
		invalidateDisplayList()
	}
	
	override protected function measure():void {
		super.measure()
		
		radius = MAX_RADIUS
		
		if (!isNaN(maxValue)) {
			radius = MIN_RADIUS + (radius-MIN_RADIUS)*_totalValue/maxValue;
		}
		
		if (radius > MAX_RADIUS) {
			_borderThickness = radius*2/MAX_RADIUS
			_borderColor = 0xFFFF00
			radius = MAX_RADIUS
		}
		
		invalidateDisplayList()
		//measuredMinHeight = measuredHeight = radius*2
		//measuredMinWidth = measuredWidth = radius*2
	}
	
	override public function styleChanged(styleProp:String):void {
		super.styleChanged(styleProp)
		if (!styleProp) return;
		
		var p:String = "_"+styleProp
		if (['borderThickness', 'borderAlpha', 'borderColor', 
			'lineThickness', 'lineAlpha', 'lineColor', 
			'fillAlpha'].indexOf(styleProp) >= 0) {
			
			this[p] = getStyle(styleProp)
			invalidateDisplayList()
			return
		}
		
		if (styleProp == "dropShadow") 
			invalidateDisplayList()
			
	}
	
	override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
		super.updateDisplayList(unscaledWidth, unscaledHeight)
		
		if (!values.length) return;
		
		if (!getStyle('dropShadow') || getStyle('dropShadow') == 'yes') {
			alpha = _fillAlpha
			filters = [new DropShadowFilter()]
		}else {
			filters = null
		}
		
		graphics.clear();
		
		graphics.lineStyle(_lineThickness, _lineColor, _lineAlpha);
		graphics.beginFill(values[0].color, _fillAlpha);
		graphics.drawCircle(0, 0, radius);
		graphics.endFill();
		
		var angle:Number
		var startAngle:Number = 0
		if (values.length>1) {
			for (var i:int = 1; i<values.length; i++) {
				angle = 360*values[i].value/_totalValue
				drawSector(0, 0, 0, radius, angle, startAngle, values[i].color)
				startAngle += angle
			}
		}
		
		if (_borderThickness && _borderAlpha) {
			graphics.lineStyle(_borderThickness, _borderColor, _borderAlpha);
			graphics.beginFill(0, 0);
			graphics.drawCircle(0, 0, radius+_borderThickness/2);
			graphics.endFill();
		}
	}
	
	
	private var _title:String;
	public function set title(value:String):void {
		_title = value;
		toolTip = title
	}

	public function get title():String {
		return _title;
	}

	private function drawSector(x:Number, y:Number, r:Number, R:Number, angle:Number, startAngle:Number, color:uint=0):void
	{
		//graphics.clear();
		graphics.lineStyle (_lineThickness, _lineColor, _lineAlpha, true);
		
		/*
		var matrix:Matrix = new Matrix();
		matrix.createGradientBox(2*R, 2*R, 0, -R, -R);
		graphics.beginGradientFill(GradientType.RADIAL, [0x0000FF, 0x0000FF], [.5, 0], [0, 255], matrix, 
			SpreadMethod.PAD, InterpolationMethod.LINEAR_RGB);
		*/
		graphics.beginFill(color, _fillAlpha);
		 
		if (Math.abs(angle) > 360)
		{
			angle=360;
		}
		 
		var n:Number = Math.ceil(Math.abs(angle) / 45);
		var angleA:Number=angle / n;
		 
		angleA = angleA * Math.PI / 180;
		startAngle = (startAngle-90) * Math.PI / 180;
		 
		var startB:Number = startAngle;
		 
		//start edge
		graphics.moveTo(x + r * Math.cos(startAngle), y + r * Math.sin(startAngle));
		graphics.lineTo(x + R * Math.cos(startAngle), y + R * Math.sin(startAngle));
		 
		//outer arc
		for (var i:int=1; i <= n; i++)
		{
			startAngle += angleA;
		 
			var angleMid1:Number=startAngle - angleA / 2;
			var bx:Number = x + R / Math.cos(angleA / 2) * Math.cos(angleMid1);
			var by:Number = y + R / Math.cos(angleA / 2) * Math.sin(angleMid1);
			var cx:Number = x + R * Math.cos(startAngle);
			var cy:Number = y + R * Math.sin(startAngle);
			 
			graphics.curveTo(bx, by, cx, cy);
		}
		 
		// start position of inner arc
		graphics.lineTo(x + r * Math.cos(startAngle),y + r * Math.sin(startAngle));
		 
		//inner arc
		for (var j:int = n; j >= 1; j--)
		{
			startAngle-= angleA;
			 
			var angleMid2:Number=startAngle + angleA / 2;
			var bx2:Number=x + r / Math.cos(angleA / 2) * Math.cos(angleMid2);
			var by2:Number=y + r / Math.cos(angleA / 2) * Math.sin(angleMid2);
			var cx2:Number=x + r * Math.cos(startAngle);
			var cy2:Number=y + r * Math.sin(startAngle);
			 
			graphics.curveTo(bx2, by2, cx2, cy2);
		}
		 
		// end position of inner arc.
		graphics.lineTo(x + r * Math.cos(startB),y + r * Math.sin(startB));
		 
		//done
		graphics.endFill();
	}
}
}